package cn.zhf.shop.service.impl;


import cn.hutool.http.HttpUtil;
import cn.zhf.shop.entity.*;
import cn.zhf.shop.entity.lesson.Lesson;
import cn.zhf.shop.entity.lesson.LessonOverview;
import cn.zhf.shop.entity.organization.Organization;
import cn.zhf.shop.entity.search.OrderSearch;
import cn.zhf.shop.mapper.*;
import cn.zhf.shop.sdk.WXPayUtil;
import cn.zhf.shop.service.OrdersService;
import cn.zhf.shop.utils.H5WXPayUtils;
import cn.zhf.shop.utils.OrderUtil;
import cn.zhf.shop.utils.PayUtils;
import cn.zhf.shop.utils.UnionPay;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

import static cn.zhf.shop.utils.UnionPay.*;

@Component
public class OrdersServiceImpl implements OrdersService {

    @Resource
    private OrdersMapper ordersMapper;

    @Resource
    private ShoppingOrderMapper shoppingOrderMapper;

    @Resource
    private LessonMapper lessonMapper;

    @Resource
    private CampusMapper campusMapper;

    @Resource
    private OrganizationMapper organizationMapper;

    @Resource
    private  ConsoleUserMapper consoleUserMapper;

    private Logger logger= LoggerFactory.getLogger(getClass());

    @Override
    public Message<?> insert(Orders o) {
        o.setId(OrderUtil.genOrderId());
        o.setCreateTime(new Date());
        o.setState(0);
        return ordersMapper.insertSelective(o) > 0 ? Message.success(null).add(o) : Message.fail(null);
    }

    @Override
    public Message<Orders> getByOrderId(String id) {
        Orders o=ordersMapper.selectByPrimaryKey(id);
        return o == null ? Message.fail(null) : Message.success(null).add(o);
    }

    @Override
    public Message<List<Orders>> getAllOrders() {
            List<Orders> ordersList= ordersMapper.selectAll();
            List<Orders> ordersList1 =  new LinkedList<>();
            for(int i=0;i<ordersList.size();i++){
                Orders orders= ordersList.get(i);
                int LessonId = orders.getLessonId();
                if(LessonId==-1){
                    ordersList1.add(orders);
                    continue;
                }else{
                    Lesson lesson=lessonMapper.selectByPrimaryKey(LessonId);
                    orders.setLessonName(lesson.getLessonName());
                    ordersList1.add(orders);
                }
            }
            return Message.success(null).add(ordersList1);
    }

    @Override
    public Message<List<Orders>> getByUserId(String userId) {
        List<Orders> ordersList = ordersMapper.selectByUserId(userId);
        for(Orders orders : ordersList){
            if(orders.getLessonId()==-1){
                Campus campus = campusMapper.selectByCampusName(orders.getCampusName());
                orders.setLessonImg(campus.getCampusImg());
            }else{
                Lesson lesson = lessonMapper.selectByPrimaryKey(orders.getLessonId());
                orders.setLessonImg(lesson.getLessonImg());
            }
        }
        return Message.success(null).add(ordersList);
    }

    @Override
    public Message<List<Orders>> getByCampusName(String campusName) {
        return Message.success(null).add(ordersMapper.selectByCampusName(campusName));
    }

    @Override
    public List<Orders> getByCampusName2(String campusName) {
        return ordersMapper.selectByCampusName(campusName);
    }
    @Override
    public Message<List<Orders>> getByState(Integer state) {
        return Message.success(null).add(ordersMapper.selectByState(state));
    }

    @Override
    public Message<List<Orders>> getByStateAndUserId(String userId, Integer state) {
        return Message.success(null).add(ordersMapper.selectByStateAndUserId(state, userId));
    }

    @Override
    public Message<?> payOrder(String orderId) {
        Orders o=ordersMapper.selectByPrimaryKey(orderId);
        try {
            String rs=PayUtils.unifiedOrder(o.getId(),o.getCampusName()+"课程",o.getTotalPrice().multiply(BigDecimal.valueOf(1L)).intValue());
            Message.success(null).add(rs);
        } catch (Exception e) {
            return Message.fail("下单失败");
        }
        return Message.fail(null);
    }

    @Override
    public Message<?> validOrder(String orderId){
        if (PayUtils.verifyOrder(orderId)) {
            if (updatePayInfo(orderId,3)) {
                return Message.success("订单已支付成功，数据库已更新");
            }
            return Message.success("订单支付成功，数据库状态更新失败");
        }
        return Message.fail("订单未支付");
    }

    @Override
    public String resolveWeChatNotify(HttpServletRequest req)throws Exception  {
        Map rs=new HashMap();
        String xml=PayUtils.parseRequst(req);
        String xrs="";
        logger.info("收到了来自微信官方的支付成功通知：{}",xml);
        // valid 当xml验证签名成功 返回订单号，否则返回ERROR
        String valid=PayUtils.resolveOrderNotify(xml);
        if (valid.equals("ERROR")){
            //数据包解析失败 或 不是官方数据包
            logger.info("数据包解析失败 或 不是官方数据包");
            rs.put("return_code","FAIL");
            rs.put("return_msg","参数格式校验错误");
            xrs= WXPayUtil.mapToXml(rs);
        }else{
            logger.info("微信官方的支付成功通知，订单号{}",valid);
            updatePayInfo(valid,3);
            rs.put("return_code","SUCCESS");
            rs.put("return_msg","");
            xrs=WXPayUtil.mapToXml(rs);
        }
        return xrs;


//        try {
//            String orderId=(String)PayUtils.resolveOrderNotify(xml);
//            if (!orderId.equals("ERROR")) {
//                return updatePayInfo(orderId) ? 0 : -1;
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//            return -1;
//        }
//        return -1;
    }

    @Override
    public String resolveWeChatNotifyH5(HttpServletRequest req) throws Exception {
        Map rs=new HashMap();
        String xml=PayUtils.parseRequst(req);
        String xrs="";
        logger.info("收到了来自微信官方的支付成功通知：{}",xml);
        // valid 当xml验证签名成功 返回订单号，否则返回ERROR
        String valid=PayUtils.resolveOrderNotify(xml);
        if (valid.equals("ERROR")){
            //数据包解析失败 或 不是官方数据包
            logger.info("数据包解析失败 或 不是官方数据包");
            rs.put("return_code","FAIL");
            rs.put("return_msg","参数格式校验错误");
            xrs= WXPayUtil.mapToXml(rs);
        }else{
            logger.info("微信官方的支付成功通知，订单号{}",valid);
            updatePayInfo(valid,3);
            rs.put("return_code","SUCCESS");
            rs.put("return_msg","");
            xrs=WXPayUtil.mapToXml(rs);
        }
        return xrs;
    }



    @Override
    public boolean updatePayInfo(String orderId,int pay) {
        if (shoppingOrderMapper.selectByPrimaryKey(orderId)!=null){
            ShoppingOrder shoppingOrder =shoppingOrderMapper.selectByPrimaryKey(orderId) ;
            if (shoppingOrder.getOrderId()!=null){
                String[] str1 = shoppingOrder.getOrderId().split(";");
                for(int i=0;i<str1.length;i++)
                {
                    Orders orders = ordersMapper.selectByPrimaryKey(str1[i]);
                    orders.setState(1);
                    orders.setPayType(pay);
                    Date date = new Date();
                    orders.setPayTime(date);
                    Lesson lesson = lessonMapper.selectByPrimaryKey(orders.getLessonId());
                    lesson.setBuyCount(lesson.getBuyCount()+orders.getAmount());
                    Campus campus=campusMapper.selectByPrimaryKey(lesson.getCampus());
                    orders.setHead(campus.getHead());
                    Organization organization =organizationMapper.selectByPrimaryKey(campus.getOrgId());
                    orders.setReferenceId(organization.getReferenceId());

                    lessonMapper.updateByPrimaryKey(lesson);
                    if (ordersMapper.updateByPrimaryKeySelective(orders)>0){
                        continue;
                    }
                    else {
                        return false;
                    }
                }
            }
        }
        else if(ordersMapper.selectByPrimaryKey(orderId)!=null){
            Orders orders = ordersMapper.selectByPrimaryKey(orderId);
            orders.setState(1);
            orders.setPayType(pay);
            Date date = new Date();
            orders.setPayTime(date);
            Lesson lesson = lessonMapper.selectByPrimaryKey(orders.getLessonId());
            lesson.setBuyCount(lesson.getBuyCount()+orders.getAmount());
            lessonMapper.updateByPrimaryKey(lesson);
            Campus campus=campusMapper.selectByPrimaryKey(lesson.getCampus());
            orders.setHead(campus.getHead());
            Organization organization =organizationMapper.selectByPrimaryKey(campus.getOrgId());
            orders.setReferenceId(organization.getReferenceId());
            if(ordersMapper.updateByPrimaryKeySelective(orders)>0){
                return true;
            }
            else {
                return false;
            }
        }
        return false;


    }

    @Override
    public Message<List<Orders>> boughtLesson(String userId) {
        List<Orders> refund=ordersMapper.selectByUserIdPayed(userId);
        return refund==null?Message.fail("无记录"):Message.success(null).add(refund);
    }

    @Override
    public Message<List<Orders>> getByReference(String reference) {
        List<Orders> refund=ordersMapper.selectByReferenceId(reference);
        List<Orders> refund1=new LinkedList<>();
       for(Orders orders :refund){
          ConsoleUser consoleUser =consoleUserMapper.selectByPrimaryKey(orders.getReferenceId());
          orders.setReferenceName(consoleUser.getUsername());
          if(orders.getLessonId()==-1){
            orders.setLessonName("线下课程");
          }else{
            Lesson lesson =lessonMapper.selectByPrimaryKey(orders.getLessonId());
            orders.setLessonName(lesson.getLessonName());
          }
          refund1.add(orders);
       }
        return refund1==null?Message.fail("无记录"):Message.success(null).add(refund1);
    }

    @Override
    public Message<List<Orders>> getByCam(String hand) {
        List<Orders> refund=ordersMapper.selectByHandIdCam(hand);
        List<Orders> refund1=new LinkedList<>();
        for(Orders orders :refund){
            if(orders.getLessonId()==-1){
                orders.setLessonName("线下课程");
            }else{
                Lesson lesson =lessonMapper.selectByPrimaryKey(orders.getLessonId());
                orders.setLessonName(lesson.getLessonName());
            }
            refund1.add(orders);
        }
        return refund1==null?Message.fail("无记录"):Message.success(null).add(refund1);
    }

    @Override
    public Message<List<Orders>> getByOrg(String hand) {
        List<Orders> refund=ordersMapper.selectByHandIdOrg(hand);
        List<Orders> ordersList1 =  new LinkedList<>();
        for(Orders orders : refund){
            int LessonId = orders.getLessonId();
            if(LessonId==-1){
                ordersList1.add(orders);
                continue;
            }else{
                Lesson lesson=lessonMapper.selectByPrimaryKey(LessonId);
                orders.setLessonName(lesson.getLessonName());
                ordersList1.add(orders);
            }
        }
        return refund==null?Message.fail("无记录"):Message.success(null).add(ordersList1);
    }

    @Override
    public Message<?> wxH5pay(String orderId,String userIp) throws Exception{
        logger.info("订单支付，订单号：{{}}",orderId);
        Orders orders = ordersMapper.selectByPrimaryKey(orderId);
        if (orders!=null){
            String rs= H5WXPayUtils.H5unifiedOrder(orderId,orders.getCampusName()+"服务",orders.getTotalPrice().multiply(BigDecimal.valueOf(100L)).intValue(),userIp);
            logger.info("订单支付结果：订单号：{{}}，结果：{{}}",orderId,rs);
            return Message.success(null).add(rs);
        }
        return Message.fail("订单不存在");
    }

    @Override
    public Message<?> wxH5payGou(ShoppingOrder shoppingOrder, String userIp) throws Exception {
        int price = 0;

        if (shoppingOrder.getOrderId()!=null)
        {

            String[] str1 = shoppingOrder.getOrderId().split(";");
            for (int i=0;i< str1.length;i++)
            {
                String orderId = str1[i];
                logger.info("订单支付，订单号：{{}}",orderId);
                Orders orders = ordersMapper.selectByPrimaryKey(orderId);
                price = price+orders.getTotalPrice().multiply(BigDecimal.valueOf(100L)).intValue();
            }
            shoppingOrder.setShoppingOrderPrice(new BigDecimal(price));
            Orders orders = ordersMapper.selectByPrimaryKey(str1[0]);
            String rs= H5WXPayUtils.H5unifiedOrder(shoppingOrder.getShoppingOrderId(),orders.getCampusName()+"服务......",price,userIp);
            logger.info("购物车订单支付结果：购物车订单号：{{}}，结果：{{}}",shoppingOrder.getShoppingOrderId(),rs);
            return Message.success(null).add(rs);
        }
        return Message.fail("订单不存在");
    }

    @Override
    public int ShoppingOrderinsert(Orders orders) {
        return ordersMapper.insertSelective(orders);
    }

    @Override
    public Message<?> unionPaySSM(String phoneNo,String txnAmt,String orderId){
        return SMS(phoneNo,txnAmt,orderId);
    }

    @Override
    public Message<?> unionPay(String txnAmt, String sms ,String cardId,String orderId) throws IOException {
        String resp= pay(txnAmt,sms,cardId,orderId);
        if("00".equals(resp)){
           Orders orders =ordersMapper.selectByPrimaryKey(orderId);
           orders.setState(1);
           orders.setPayType(0);
           Date date = new Date();
           orders.setPayTime(date);

           if(orders.getLessonId()==-1){
               orders.setPayType(2);
               Campus campus = campusMapper.selectByCampusName(orders.getCampusName());
               Organization organization =organizationMapper.selectByPrimaryKey(campus.getOrgId());
               orders.setHead(campus.getHead());
               orders.setReferenceId(organization.getReferenceId());
           }else{
               Lesson lesson = lessonMapper.selectByPrimaryKey(orders.getLessonId());
               Campus campus=campusMapper.selectByPrimaryKey(lesson.getCampus());
               Organization organization =organizationMapper.selectByPrimaryKey(campus.getOrgId());
               orders.setHead(campus.getHead());
               orders.setReferenceId(organization.getReferenceId());
               lesson.setBuyCount(lesson.getBuyCount()+orders.getAmount());
               lessonMapper.updateByPrimaryKey(lesson);
           }
           ordersMapper.updateByPrimaryKeySelective(orders);

            return Message.success("支付成功");
        }else{
            return Message.fail("支付失败 !!"+resp);
        }
    }

    @Override
    public Message<?> payByStages(String txnAmt, String sms ,String cardId,String number,String orderId)  {
        String resp= UnionPay.payByStages(txnAmt,sms ,cardId,number,orderId);
        if("00".equals(resp)){
           Orders orders =ordersMapper.selectByPrimaryKey(orderId);
            orders.setState(1);
            orders.setPayType(1);
            Date date = new Date();
            orders.setPayTime(date);

            if(orders.getLessonId()==-1){
                orders.setPayType(2);
                Campus campus = campusMapper.selectByCampusName(orders.getCampusName());
                Organization organization =organizationMapper.selectByPrimaryKey(campus.getOrgId());
                orders.setHead(campus.getHead());
                orders.setReferenceId(organization.getReferenceId());
            }else{
                Lesson lesson = lessonMapper.selectByPrimaryKey(orders.getLessonId());
                Campus campus=campusMapper.selectByPrimaryKey(lesson.getCampus());
                orders.setHead(campus.getHead());
                Organization organization =organizationMapper.selectByPrimaryKey(campus.getOrgId());
                orders.setReferenceId(organization.getReferenceId());
                lesson.setBuyCount(lesson.getBuyCount()+orders.getAmount());
                lessonMapper.updateByPrimaryKey(lesson);
            }



            ordersMapper.updateByPrimaryKeySelective(orders);

            return Message.success("支付成功");
        }else{
            return Message.fail("支付失败 !!"+resp);
        }
    }

    @Override
    public Message<?> unionpayShop(String txnAmt, String sms ,String cardId,String orderId) throws IOException {
        String resp = payShop(txnAmt,sms,cardId,orderId);
        if("00".equals(resp)){
           updatePayInfo(orderId,0);
           return  Message.success("支付成功");
        }else{
            return Message.fail("支付失败 !!"+resp);
        }
    }

    @Override
    public Message<?> payByStagesShop(String txnAmt, String sms ,String cardId,String number,String orderId)  {
        String resp =  UnionPay.payByStagesShop(txnAmt,sms ,cardId,number,orderId);
        if("00".equals(resp)){
            updatePayInfo(orderId ,1);
            return  Message.success("支付成功");
        }else{
            return Message.fail("支付失败 !!"+resp);
        }
    }

    @Override
    public List<Orders> selectByOrgName(String orgName) {
        return ordersMapper.selectByOrgName(orgName);
    }

    @Override
    public List<Orders> selectByOrgNameAndState(String orgName, Integer state) {
        return ordersMapper.selectByOrgNameAndState(orgName, state);
    }

    @Override
    public Integer countByOrgName(String orgName) {
        return ordersMapper.countByOrgName(orgName);
    }

    @Override
    public List<BigDecimal> selectTotalPriceByOrgName(String orgName) {
        return ordersMapper.selectTotalPriceByOrgName(orgName);
    }

    @Override
    public List<BigDecimal> selectTotalPriceByOrgNameAndState(String orgName, Integer state) {
        return ordersMapper.selectTotalPriceByOrgNameAndState(orgName, state);
    }

    @Override
    public Message<List<Orders>> selectBySearch1(Integer lessonId,String orgName,String campusName,String userName,Integer userId){
        List<Orders> ordersList1 =  new LinkedList<>();
        ConsoleUser consoleUser =consoleUserMapper.selectByPrimaryKey(userId);
        if(consoleUser.getUserGroup()==1){
            List<Orders> ordersList= ordersMapper.selectBySearch1(lessonId,orgName,campusName,userName);
            for(int i=0;i<ordersList.size();i++){
                Orders orders = ordersList.get(i);
                int LessonId = orders.getLessonId();
                if(LessonId==-1){
                    ordersList1.add(orders);
                    continue;
                }else{
                    Lesson lesson = lessonMapper.selectByPrimaryKey(LessonId);
                    orders.setLessonName(lesson.getLessonName());
                    ordersList1.add(orders);
                }
            }
        }else if(consoleUser.getUserGroup()==2){
            List<Orders> ordersList = ordersMapper.selectBySearch5(lessonId,orgName,campusName,userName,userId);
            for(int i=0;i<ordersList.size();i++){
                Orders orders = ordersList.get(i);
                int LessonId = orders.getLessonId();
                if(LessonId==-1){
                    ordersList1.add(orders);
                    continue;
                }else{
                    Lesson lesson = lessonMapper.selectByPrimaryKey(LessonId);
                    orders.setLessonName(lesson.getLessonName());
                    ordersList1.add(orders);
                }
            }
        }else if(consoleUser.getUserGroup()==3){
           Integer orgId=consoleUser.getOrgId();
            List<Campus> campusList= campusMapper.selectByOrgId(orgId);
            for(Campus campus : campusList){
                List<Orders> ordersList = ordersMapper.selectBySearch3(lessonId,orgName,campusName,userName,campus.getHead());
                for(int i=0;i<ordersList.size();i++){
                    Orders orders = ordersList.get(i);
                    int LessonId = orders.getLessonId();
                    Lesson lesson=lessonMapper.selectByPrimaryKey(LessonId);
                    if(orders.getLessonId()==-1){
                        ordersList1.add(orders);
                        continue;
                    }else {
                        orders.setLessonName(lesson.getLessonName());
                        ordersList1.add(orders);
                    }
                }
            }
        }else if(consoleUser.getUserGroup()==4){
            List<Orders> ordersList = ordersMapper.selectBySearch3(lessonId,orgName,campusName,userName,userId);
            for(int i=0;i<ordersList.size();i++){
                Orders orders = ordersList.get(i);
                int LessonId = orders.getLessonId();
                if(LessonId==-1){
                    ordersList1.add(orders);
                    continue;
                }else{
                    Lesson lesson = lessonMapper.selectByPrimaryKey(LessonId);
                    orders.setLessonName(lesson.getLessonName());
                    ordersList1.add(orders);
                }
            }
        }
        return Message.success(null).add(ordersList1);
    }

    @Override
    public Message<List<Orders>> slectBySearch2(String str,Integer userId){
        List<Orders> ordersList1 =  new LinkedList<>();
        ConsoleUser consoleUser =consoleUserMapper.selectByPrimaryKey(userId);

        if(consoleUser.getUserGroup()==1){
            List<Orders> ordersList= ordersMapper.selectBySearch2(str);
            for(int i=0;i<ordersList.size();i++){
                Orders orders = ordersList.get(i);
                int LessonId = orders.getLessonId();
                if(LessonId==-1){
                    ordersList1.add(orders);
                    continue;
                }else{
                    Lesson lesson = lessonMapper.selectByPrimaryKey(LessonId);
                    orders.setLessonName(lesson.getLessonName());
                    ordersList1.add(orders);
                }
            }
        }else if(consoleUser.getUserGroup()==2){
            List<Orders> ordersList=ordersMapper.selectBySearch6(str,userId);
            for(int i=0;i<ordersList.size();i++){
                Orders orders = ordersList.get(i);
                int LessonId = orders.getLessonId();
                if(LessonId==-1){
                    ordersList1.add(orders);
                    continue;
                }else{
                    Lesson lesson = lessonMapper.selectByPrimaryKey(LessonId);
                    orders.setLessonName(lesson.getLessonName());
                    ordersList1.add(orders);
                }
            }
        }else if(consoleUser.getUserGroup()==3){
               Organization organization=organizationMapper.selectByPrimaryKey(consoleUser.getOrgId());
               List<Orders> ordersList =ordersMapper.selectBySearch7(str,organization.getOrgName());
                   for(int i=0;i<ordersList.size();i++){
                       Orders orders = ordersList.get(i);
                       int LessonId = orders.getLessonId();
                       Lesson lesson=lessonMapper.selectByPrimaryKey(LessonId);
                       if(orders.getLessonId()==-1){
                           ordersList1.add(orders);
                           continue;
                       }else {
                           orders.setLessonName(lesson.getLessonName());
                           ordersList1.add(orders);
                       }
                   }

        }else if(consoleUser.getUserGroup()==4) {
            List<Orders> ordersList = ordersMapper.selectBySearch4(str, userId);
            for (int i = 0; i < ordersList.size(); i++) {
                Orders orders = ordersList.get(i);
                int LessonId = orders.getLessonId();
                if(LessonId==-1){
                    continue;
                }else{
                    Lesson lesson = lessonMapper.selectByPrimaryKey(LessonId);
                    orders.setLessonName(lesson.getLessonName());
                    ordersList1.add(orders);
                }

            }
        }
        return Message.success(null).add(ordersList1);
    }

    @Override
    public Message mohuConditionSearch(OrderSearch c) {
        List<Orders> ordersList = ordersMapper.selectByUserNameAndOrgNameAndCampusNameAndLessonIdAndPayType(c);
        for (Orders orders:ordersList)
        {
           orders.setLessonName(lessonMapper.selectByPrimaryKey(orders.getLessonId()).getLessonName());
        }

        List<Orders> ordersList1 = new LinkedList<>();
        if (ordersList.size()>0)
        {
            if (c.getMinprice()!=null)
            {
                if (c.getMaxprice()!=null)
                {
                    for (Orders orders:ordersList)
                    {
                        int price = orders.getTotalPrice().intValue()/100;
                        if (c.getMinprice()<=price&&price<=c.getMaxprice()){
                            ordersList1.add(orders);
                        }
                    }
                    return Message.success(null).add(ordersList1);
                }
                else if (c.getMaxprice()==null)
                {
                    for (Orders orders:ordersList)
                    {
                        int price = orders.getTotalPrice().intValue()/100;
                        if (c.getMinprice()<=price){
                            ordersList1.add(orders);
                        }
                    }
                    return Message.success(null).add(ordersList1);
                }
            }else if (c.getMaxprice()!=null&&c.getMinprice()==null)
            {
                for (Orders orders:ordersList)
                {
                    int price = orders.getTotalPrice().intValue()/100;
                    if (price<=c.getMaxprice()){
                        ordersList1.add(orders);
                    }
                }
                return Message.success(null).add(ordersList1);
            }
        }

        return Message.success(null).add(ordersList);
    }

    @Override
    public Message updateByPrimaryKeySelective(Orders record) {
        return ordersMapper.updateByPrimaryKeySelective(record)>0?Message.success(null):Message.fail(null);
    }


}
